<?php

namespace App\Http\Controllers\Admin;

use App\DTOS\Admin\CustomerDTO;
use App\Exceptions\ServiceException;
use App\Exports\ExcelExport;
use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\Game\BanList;
use App\Models\Game\Sale;
use App\Services\CustomerService;
use App\Utils\MyLog;
use App\Utils\ResponseUtil;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Http\Request;

class CustomerController extends Controller
{
    private CustomerService $customerService;
    private Request $request;
    public function __construct(Request $request,CustomerService $customerService)
    {
        $this->customerService = $customerService;
        $this->request = $request;
    }

    public function paginate() { //table 数据

        $dto = new CustomerDTO($this->request->all());
        $paginate = $this->customerService->paginate($dto);
        $data = $paginate->items();
        foreach($data as &$datum){
            $datum['uuid'] = (string)$datum['id'];
        }
        $res = [];
        $res['code'] = 0;
        $res['data'] = $data;
        $res['count'] = $paginate->total();
        return ResponseUtil::json($res);
    }


    public function customeractive() { //table 数据

        $dto = new CustomerDTO($this->request->all());
        $paginate = $this->customerService->customeractive($dto);
        $data = $paginate->items();
        foreach($data as &$datum){
            $datum['uuid'] = (string)$datum['id'];
        }
        $res = [];
        $res['code'] = 0;
        $res['data'] = $data;
        $res['count'] = $paginate->total();
        return ResponseUtil::json($res);
    }

    /**
     * DAU、WAU、MAU统计
     */
    public function activeUserStats()
    {
        $dto = new CustomerDTO($this->request->all());
        $stats = $this->customerService->getActiveUserStats($dto);

        $res = [];
        $res['code'] = 0;
        $res['data'] = $stats;
        return ResponseUtil::json($res);
    }

    /**
     * 游戏次数统计
     */
    public function gameTimesStats()
    {
        $dto = new CustomerDTO($this->request->all());
        $stats = $this->customerService->getGameTimesStats($dto);

        $res = [];
        $res['code'] = 0;
        $res['data'] = $stats;
        return ResponseUtil::json($res);
    }

    /**
     * 游戏时长
     */
    public function gameTimes()
    {
        $dto = new CustomerDTO($this->request->all());
        $stats = $this->customerService->getGameTimes($dto);

        $res = [];
        $res['code'] = 0;
        $res['data'] = $stats;
        return ResponseUtil::json($res);
    }

    public function export(){ //table 数据导出
        $dto = new CustomerDTO($this->request->all());
        $paginate = $this->customerService->paginate($dto);
        $excelRows = [
            ['ID','账号','密码','邀请码','真实姓名','身份证号','创建时间','登录区服','登录时间']
        ];
        foreach($paginate->items() as $datum){
            $excelRows[] = [$datum['id'], $datum['phone'],$datum['password'],$datum['invite_code'],$datum['real_name'],
                strval($datum['identity_code']),$datum['created_at'],$datum['lastloginserverid'],$datum['logindata']
            ];
        }

        $excel = new ExcelExport($excelRows);
        return Excel::download($excel, '用户.xlsx');
    }

    public function detail($id)
    {
        $customer = Customer::query()->where('id',$id)->first();
        $customer['password'] = '';
        return ResponseUtil::success($customer);
    }

    public function resetPass($id)
    {
        $password = $this->request->get('password');
        if (!preg_match("/^[a-zA-Z0-9]+$/",$password)){
            return ResponseUtil::error('密码仅支持数字加字母');
        }
        $enPassword = Crypt::encryptString($password);
        Customer::query()->where('id',$id)->update(['password'=>$enPassword]);
        return ResponseUtil::success();
    }

    public function edit($id)
    {

        $mobile = $this->request->get('mobile');
        $identity_code = $this->request->get('identity_code');
        $real_name = $this->request->get('real_name');
        $invite_code = $this->request->get('invite_code');
        $ids = $this->request->get('customer_id');
        MyLog::info('查看传入的ID'.json_encode($ids));
        $customer = Sale::query()->where('code',$invite_code)->first();

        if(!$customer&&!$real_name){
            return ResponseUtil::error('邀请码不存在');
        }
        $updateData = [];
        if (!empty($mobile)) {
            $updateData['mobile'] = $mobile;
        }
        if (!empty($invite_code)) {
            $updateData['invite_code'] = $invite_code;
        }
        if (!empty($identity_code)) {
            $updateData['identity_code'] = $identity_code;
        }

        if (!empty($real_name)) {
            $updateData['real_name'] = $real_name;
        }

        if (!empty($updateData)) {
            if (strpos($ids, ',') !== false) {
                $idArray = explode(',', $ids);
                Customer::query()->whereIn('id', $idArray)->update($updateData);
            }else{
                MyLog::info('查看传入的ID1'.json_encode($id));
                MyLog::info('查看传入的ID'.json_encode($ids));

                Customer::query()->where('id', $id)->update($updateData);
            }
        }
        return ResponseUtil::success();
    }

    public function showPass($id)
    {
        try{
            $customer = Customer::query()->find($id);
            if ($customer->password===null){
                throw new \Exception('密码为NULL');
            }
            $enPassword = data_get($customer,'password');
            return ResponseUtil::success(['password'=>Crypt::decryptString($enPassword)]);
        }catch(\Exception $e){
            return ResponseUtil::error($e->getMessage());
        }
    }

    public function autoGen()
    {
        $data = request()->only(['number','prefix','password','number1','number2']);
        $number1 = (int)data_get($data,'number1');
        $number2 = (int)data_get($data,'number2');

      //  $prefix = data_get($data,'prefix');

        $generatedPhones = []; // 用于存储已生成的账户名

        $password = data_get($data,'password');
        for($i=$number1;$i<$number2;$i++){
            $this->genCustomer( $password, $generatedPhones);
        }
        return ResponseUtil::success();
    }

    private function genCustomer($password,&$generatedPhones){ //创建账号,递归创建
        $username = $this->generateUniquePhone($generatedPhones);

        if (!$username) {
            return false; // 如果无法生成唯一账户名，返回 false
        }


        $enPassword = Crypt::encryptString($password);
        $data = [
            'id'=>getSnowFlakeId(),
            'phone'=>$username,
            'channel_type'=>1,
            'password'=>$enPassword,
            'created_at'=>now()->format('Y-m-d H:i:s')
        ];
        Customer::query()->insert($data);
        return true;
    }
    private function generateUniquePhone( &$generatedPhones)
    {
        do {
            $username =$this->randomString();
        } while (in_array($username, $generatedPhones) || Customer::query()->where('phone', $username)->exists());

        $generatedPhones[] = $username; // 存储已生成的账户名
        return $username;
    }

    private function randomString($length = 7)
    {
        $letters = substr(str_shuffle("abcdefghijklmnopqrstuvwxyz"), 0, 5);
        $numbers = rand(10, 99);
        return $letters . $numbers;
    }


    public function add(){
        {
            DB::beginTransaction();
            try {
                $insert = [];

                $customerDTO = new CustomerDTO($this->request->all());
                $phone = $customerDTO->getPhone();
                $password = $customerDTO->getPassword();

                $insert['phone'] = $phone;
                $insert['mobile'] = $phone;
                $insert['password'] = Crypt::encryptString($password);
                $insert['id'] = getSnowFlakeId();
                $insert['created_at']=date("Y-m-d H:i:s");


                DB::commit();
                Customer::query()->insert($insert);
                return ResponseUtil::success();
            } catch (ServiceException $e){
                DB::rollBack();
                throw $e;
            } catch (\Exception $e){
                DB::rollBack();
                throw new ServiceException($e->getMessage());
            }
        }

    }


    /**
     * 首页游戏数据汇总
     */
    public function init()
    {
        $dto = new CustomerDTO($this->request->all());
        $stats = $this->customerService->getDashboardStats($dto);

        $res = [];
        $res['code'] = 0;
        $res['data'] = $stats;
        return ResponseUtil::json($res);
    }

    /**
     * 榜单类型 查询
     */
    public function top()
    {
        $dto = new CustomerDTO($this->request->all());
        $stats = $this->customerService->gettop($dto);

        $res = [];
        $res['code'] = 0;
        $res['count'] = data_get($stats,'count',0);
        $res['data'] = data_get($stats,'data',[]);
        return ResponseUtil::json($res);
    }


    /**
     * 游戏进度分布 查询
     */
    public function progress()
    {
        $dto = new CustomerDTO($this->request->all());
        $stats = $this->customerService->getprogress($dto);

        $res = [];
        $res['code'] = 0;
        $res['count'] = data_get($stats,'count',0);
        $res['data'] = data_get($stats,'data',[]);
        return ResponseUtil::json($res);
    }

    /**
     * 导出游戏进度数据
     */
    public function exportProgress()
    {
        try {
            $gameArea = $this->request->get('gameArea');
            $type = $this->request->get('type');
            $exportDate = $this->request->get('exportDate');

            if (!$gameArea || !$type || !$exportDate) {
                return ResponseUtil::json(['code' => 1, 'message' => '参数不完整']);
            }

            if (!in_array($type, ['level', 'task'])) {
                return ResponseUtil::json(['code' => 1, 'message' => '不支持的数据类型']);
            }

            $exportData = $this->customerService->exportProgressData($gameArea, $type, $exportDate);
            
            // 使用 Excel 导出
            return Excel::download(new ExcelExport($exportData['data'], $exportData['title']), $exportData['filename']);

        } catch (\Exception $e) {
            MyLog::error('导出游戏进度数据失败: ' . $e->getMessage());
            return ResponseUtil::json(['code' => 1, 'message' => '导出失败: ' . $e->getMessage()]);
        }
    }

}
